<?php

namespace App\HttpController\Api;

use App\Think\Config;
use App\Think\Db;
use App\Think\Validate;
use App\Model\GameLog as GameLogModel;
use App\Model\Notice as NoticeModel;

/**
 * 代理接口Agent
 */
class Agent extends ApiBase
{
    protected $noNeedLogin = ['agent_conf'];

    /**
     * 代理配置信息
     */
    public function agent_conf(){
        $conf = Config::get('Project.agent');
        return $this->success(__('success'), $conf);
    }

    /**
     * 代理申请
     * ApiMethod (POST)
     * @param string $full_name 姓名
     * @param string $mobile 手机
     * @param string $code 手机验证码
     * @param string $apply_reason 申请理由
     * @param string $invite_code 邀请码
     */
    public function apply(){
        $full_name    = $this->input('full_name');
        $mobile       = $this->input('mobile');
        $code         = $this->input('code');
        $invite_code  = $this->input('invite_code');
        $apply_reason = $this->input('apply_reason');

        if (!$full_name || !$mobile || !$code || !$apply_reason) return $this->error(__('请求参数不完整'));
        if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) return $this->error(__('手机号格式不正确'));

        //上级邀请ID
        $invite_user_id = db_get_field('user', "invite_code='{$invite_code}'", 'id');
        if(empty($invite_user_id)) $invite_user_id = 1;

        $agent_info = db_get_row('agent',"user_id='{$this->auth->id}'");
        if( !is_null($agent_info) && $agent_info['status']!=2 ) return $this->error(__('您已提交过代理申请,请不要重复操作'));
        $arr = [
            'user_id'      => $this->auth->id,
            'parent_id'    => $invite_user_id,
            'full_name'    => $full_name,
            // 'parent_id'    => (int)$this->auth->invite_user_id,
            'mobile'       => $mobile,
            'apply_reason' => $apply_reason,
            'status'       => '3',
            'createtime'   => time()
        ];
        if($agent_info){
            $arr['status'] = 0;
            db_edit('agent', $arr, "user_id='{$this->auth->id}'");
        }else{
            db_add('agent', $arr);
        }
        //发送通知
        NoticeModel::agent_apply([ 'user_id'=>$this->auth->id ]);
        return $this->success(__('success'));
    }

    /**
     * 代理信息&财务报表
     *  @param string $month 开始时间|可选|默认当前月,格式202004
     *  @param string $view_detail 显示会员明细|0=不显示|默认,1=显示
     */
    public function index(){
        $month = $this->input('month');
        $view_detail = $this->input('view_detail');

        $user_id = $this->auth->id;
        $agent = Db::name('agent')->where("user_id='{$user_id}'")->find();
        if(!$agent) return $this->error(__('您还不是代理'));
        $months = Db::name('stats_user_month')->field('distinct month')->where("user_id='{$this->auth->id}'")->cache(60)->column('month');
        //本月统计
        $month = empty($month) ? date('Ym') : $month;
        $v = Db::name('stats_agent_month')->where("user_id='{$this->auth->id}' AND month='{$month}'")->cache(60)->find();
        $stats = [
            'total_under'=>$v['total_under'], 'total_invite'=>$v['total_invite'], 'total_active'=>$v['total_active'], 
            'total_recharge'=>$v['total_recharge'], 'total_cashout'=>$v['total_cashout'], 
            'total_valid'=>$v['total_valid'], 'total_winlose'=>$v['total_winlose'], 'total_plat_fee'=>$v['total_plat_fee']<0 ? 0 : $v['total_plat_fee'], 
            'total_netwin'=>$v['total_netwin'], 'total_rebate'=>$v['total_rebate'],'total_bonus'=>$v['total_bonus'],
            'user_comm'=>$v['user_comm'],'agent_comm'=>$v['agent_comm'],'total_comm'=>$v['total_comm'],'status_comm'=>$v['status_comm'], 'remain_comm'=>$v['remain_comm'], 'last_remain_comm'=>$v['last_remain_comm']
        ];
        $stats = $this->_data_format($stats);
        //显示会员明细
        $sub_list = [];
        if($view_detail == 1){
            $where_users = db_where_in('user_id',  Db::name('user')->where("invite_user_id={$this->auth->id}")->cache(60)->column('id') );
            $res = Db::name('stats_user_month')->where("$where_users AND month BETWEEN '{$month}' AND '{$month}'")->limit(100)->select();

            $where_ids = db_where_in('id',  array_column($res, 'user_id') );
            $users = Db::name('user')->field('id,username')->where($where_ids)->select();
            foreach ($res as $k => $v) {
                $sub_list[$k] = $v;
                $sub_list[$k]['total_winlose'] = (string)-$v['total_winlose'];
                $sub_list[$k]['username'] = arr_field($users, 'id', $v['user_id'], 'username');
            }
        }
        return $this->success(__('success'), ['agent'=>$agent, 'stats'=>$stats, 'months'=>$months, 'sub_list'=>$sub_list]);
    }

    /**
     * 提现申请
     * ApiMethod (POST)
     * @param string $money   金额
     * @param string $bank_id 银行卡ID
     * @param string $paypass 取款密码
     */
    public function cashout()
    {
        $money = $this->input("money");
        $bank_id = $this->input("bank_id");
        $paypass = $this->input("paypass");

        $user_id = $this->auth->id;
        if(!$money || !$bank_id || $money<=0) return $this->error(__('请求参数不完整'));
        if($money > 50000) return $this->error(__('单次提款金额不能大于5万'));
        $bank_info = db_get_row('user_bank',"id='{$bank_id}' AND user_id='{$user_id}'");
        if(!$bank_info) return $this->error(__('请先绑定银行卡'));

        //操作太频繁限制
        $opt_time = cache("agentCashoutTime:{$user_id}");
        if($opt_time>10) return $this->error(__('操作太频繁,请稍后操作'));
        cache("agentCashoutTime:{$user_id}",$opt_time+1, 60);

        $agent = Db::name('agent')->where("user_id='{$user_id}'")->find();
        if($agent['status'] != 1) return $this->error(__('非代理用户不能提现'));
        if($money > $agent['money']) return $this->error(__('提款金额不能大于代理账户余额'));
        if($this->auth->getEncryptPassword($paypass) != $this->auth->paypass && !empty($this->auth->paypass)) return $this->error(__('取款密码不正确'));
        
        $param = $this->request->param();
        $param['user_id'] = $user_id;
        $param = array_merge($param, $bank_info);
        Db::startTrans();
        try {
            //记录日志
            Db::name('agent_cashout')->insert([
                'user_id'   => $user_id,
                'order_sn'  => order_sn(),
                'money'     => $money,
                'account'   => $param['account'],
                'bank_name' => $param['bank_name'],
                'bank_no'   => $param['bank_no'],
                'card_type' => $param['card_type'],
                'memo'      => isset($param['memo']) ? $param['memo'] : '',
                'createtime' => time()
            ]);
            //冻结余额
            Db::name('agent')->where("user_id='{$user_id}'")->update([ 'money' => Db::raw("money-{$money}"), 'money_freeze' => Db::raw("money_freeze+{$money}") ]);
            Db::commit();
        } catch (Exception $e) {
            $this->setError($e->getMessage());
            Db::rollback();
            return $this->error(__('申请失败'));
        }
        return $this->success(__('提现申请成功,请耐心等待~'));
    }
    /**
     * 提现记录
     * @param string $starttime 开始时间|格式2020-01-01
     * @param string $endtime   结束时间|格式2020-01-01
     * @param string $page  当前页数|可选
     */
    public function cashout_log(){
        $page = $this->input("page");
        $starttime = $this->input("starttime");
        $endtime   = $this->input("endtime");
        // if(!$starttime || !$endtime) return $this->error(__('请求参数不完整'));

        if(!$starttime) $starttime = '0000-00-00';
        if(!$endtime)   $endtime   = date('Y-m-d');
        if($page <= 0) $page = 1;
        $where = " createtime between ".strtotime($starttime." 00:00:00")." AND ".strtotime($endtime." 23:59:59");
        $where .= " AND user_id='{$this->auth->id}' ";
        $data = Db::name('agent_cashout')->where($where)->page("{$page},20")->order("id DESC")->select(); 
        return $this->success(__('success'), $data);
    }

    /**
     * 佣金报表
     * @param string $month 开始时间|格式202005
     * @param string $type  佣金类型|user=会员佣金,agent=代理佣金
     */
    public function report_comm_log(){
        $month = $this->input('month');
        $type  = $this->input('type');
        $month = empty($month) ? date('Ym') : $month;
        if(!$month || !$type) return $this->error(__('请求参数不完整'));

        $sub_list = [];
        //本月统计
        $months = Db::name('stats_user_month')->field('distinct month')->where("user_id='{$this->auth->id}'")->cache(60)->column('month');
        $v = Db::name('stats_agent_month')->where("user_id='{$this->auth->id}' AND month='{$month}'")->cache(60)->find();
        $stats = [
            'total_under'=>$v['total_under'], 'total_invite'=>$v['total_invite'], 'total_active'=>$v['total_active'], 
            'total_recharge'=>$v['total_recharge'], 'total_cashout'=>$v['total_cashout'], 
            'total_valid'=>$v['total_valid'], 'total_winlose'=>$v['total_winlose'], 'total_plat_fee'=>$v['total_plat_fee']<0 ? 0 : $v['total_plat_fee'], 
            'total_netwin'=>$v['total_netwin'], 'total_rebate'=>$v['total_rebate'],'total_bonus'=>$v['total_bonus'],
            'user_comm'=>$v['user_comm'],'agent_comm'=>$v['agent_comm'],'total_comm'=>$v['total_comm'],'status_comm'=>$v['status_comm'], 'remain_comm'=>$v['remain_comm'], 'last_remain_comm'=>$v['last_remain_comm'], 'trim_comm'=>$v['trim_comm']
        ];
        $stats = $this->_data_format($stats);

        //会员佣金 本月统计
        if($type == 'user'){
            $user_ids = db_where_in('user_id',  Db::name('user')->where("invite_user_id='{$this->auth->id}' AND is_agent=0")->cache(60)->column('id') );
            $sub_list = Db::name('stats_user_month')->where("$user_ids AND month BETWEEN '{$month}' AND '{$month}'")->select();
        }
        //代理佣金 本月统计
        if($type == 'agent'){
            $agent_list = Db::name('agent')->field('user_id,parent_id,type,comm_type,comm_rate')->cache(60)->select();
            $agent = arr_row( $agent_list, 'user_id', $this->auth->id );
            //下级代理 && 代理对应的会员信息
            $agent_ids = Db::name('agent')->where("parent_id={$agent['user_id']}")->cache(60)->column('user_id');
            $users = Db::name('user')->field('invite_code,id,username')->where(db_where_in('id',  $agent_ids ))->cache(60)->select();
            //下级代理统计
            $where_condition = db_where_in('user_id',  $agent_ids )." AND month BETWEEN '{$month}' AND '{$month}' "; 
            $sub_agent_stats = Db::name('stats_agent_month')->where($where_condition)->select();
            $agent_comm = $comm_money = $agent_rate = 0;
            foreach ($sub_agent_stats as $kk => $vv) {
                $sub_list[$kk] = $vv;
                $sub_agent = arr_row($agent_list, 'user_id', $vv['user_id']);
                if($vv['total_netwin'] == 0) continue;
                $agent_rate = $agent['comm_type'] == 0 ? $agent['comm_rate'] : $agent['comm_rate']-$sub_agent['comm_rate'];
                $comm_money = number_format($vv['total_netwin']*$agent_rate/100, 2);
                $agent_comm = $agent_comm+$comm_money;

                $sub_list[$kk]['agent_rate']  = arr_field($agent_list, 'user_id', $vv['user_id'], 'comm_rate');//$agent_rate;
                $sub_list[$kk]['agent_comm']  = (string)$agent_comm;
                
                $sub_list[$kk]['username']    = arr_field($users, 'id', $vv['user_id'], 'username');
                $sub_list[$kk]['invite_code'] = arr_field($users, 'id', $vv['user_id'], 'invite_code');
            }

            //代理佣金 20200619
            /*$sub_list = [];
            $sub_agents = explode(',', $v['agent_comm_str']);
            if(count($sub_agents)>0){
                foreach ($sub_agents as $k => $v) {
                    list($tmp_user_id, $tmp_agent_comm, $tmp_agent_rate) = explode('|', $v);
                    $sub_list[$k] = Db::name('stats_agent_month am')
                        ->field('am.*,u.username,u.invite_code')->join('user u', 'am.user_id=u.id', 'LEFT')
                        ->where("am.user_id='{$tmp_user_id}' AND am.month BETWEEN '{$month}' AND '{$month}' ")->find();
                    $sub_list[$k]['agent_rate'] = $tmp_agent_rate;
                    $sub_list[$k]['total_comm'] = $tmp_agent_comm;
                }
            }*/

        }
        return $this->success(__('success'), ['stats'=>$stats, 'sub_list'=>$sub_list, 'months'=>$months]);
    }

    /**
     * 平台费&总输赢报表
     * @param string $starttime 开始时间|格式2020-01-01
     * @param string $endtime   结束时间|格式2020-01-01
     */
    public function report_fms(){
        $starttime = $this->input('starttime');
        $endtime   = $this->input('endtime');

        $where = " user_id IN (SELECT id FROM fa_user WHERE invite_user_id='{$this->auth->id}' AND is_agent=0)";
        $starttime = !empty($starttime) ? strtotime($starttime." 00:00:00") : '';
        $endtime   = !empty($endtime)   ? strtotime($endtime." 23:59:59") : time();
        $where .= " AND updatetime BETWEEN '{$starttime}' AND '{$endtime}'";
        //查询列表
        $plat_list = platform_list();
        $list = $total = [];
        list($total['total_valid'],$total['total_winlose'],$total['total_plat_fee']) = [0,0,0];
        $res = Db::name('game_log')->field('plat_key,SUM(money_valid) money_valid,SUM(money_winlose) money_winlose,SUM(money_plat_fee) money_plat_fee')->group('plat_key')->where($where)->cache(120)->select();
        foreach ($plat_list as $k => $v) {
            $list[$k] = $v;
            $row = arr_row($res, 'plat_key', $v['key']);
            $_tmp['money_valid'] = isset($row['money_valid']) ? (float)$row['money_valid'] : 0;
            $_tmp['money_winlose'] = isset($row['money_winlose']) ? (float)$row['money_winlose'] : 0;
            $_tmp['money_plat_fee'] = (isset($row['money_plat_fee']) && $row['money_plat_fee']>0) ? (float)$row['money_plat_fee'] : 0;

            $list[$k] = [
                'key'            => $v['key'],
                'name'           => $v['name'],
                'money_valid'    => (string)$_tmp['money_valid'],
                'money_winlose'  => (string)$_tmp['money_winlose'],
                'money_plat_fee' => (string)$_tmp['money_plat_fee']
            ];

            $total['total_valid']    = (string)($total['total_valid'] + $_tmp['money_valid']);
            $total['total_winlose']  = (string)($total['total_winlose'] + $_tmp['money_winlose']);
            $total['total_plat_fee'] = (string)($total['total_plat_fee'] + $_tmp['money_plat_fee']);
        }
        // exit;
        // foreach ($res as $k => $v) {
        //     $list[$k] = $v;
        //     $list[$k]['name'] = arr_field($plat_list, 'key', $v['plat_key'], 'name');
        //     $list[$k]['fee']  = arr_field($plat_list, 'key', $v['plat_key'], 'fee');
        // }

        //查询总数
        // $total = Db::name('game_log')->field('SUM(money_valid) total_valid, SUM(money_winlose) total_winlose, SUM(money_plat_fee) total_plat_fee')->cache(120)->where($where)->find();
        // $total = $this->_data_format($total);
        return $this->success(__('success'), ['list'=>$list, 'total'=>$total]);
    }

    /**
     * 下级用户
     * @param string $page     当前页数 
     * @param string $username 姓名|可选
     * @param string $starttime 开始时间|可选|格式2020-01-01
     * @param string $endtime   结束时间|可选|格式2020-01-01
     */
    public function subuser_list(){
        $page   = $this->input('page');
        $username  = $this->input('username');
        $starttime = $this->input('starttime');
        $endtime   = $this->input('endtime');

        $where = " invite_user_id='{$this->auth->id}' AND is_agent=0";
        if(!empty($username))  $where .= " AND username LIKE '%{$username}%'";
        $starttime = !empty($starttime) ? strtotime($starttime." 00:00:00") : '';
        $endtime   = !empty($endtime)   ? strtotime($endtime." 23:59:59") : time();
        $where .= " AND jointime BETWEEN '{$starttime}' AND '{$endtime}'";
        //会员列表
        $res = Db::name('user')->field('id,username,mobile,logintime,jointime,invite_code')->where($where)->order('id DESC')->page("{$page},20")->select();
        //会员本月统计
        $where_users = db_where_in('user_id', array_column($res, 'id') );
        $month = 
        $stats = Db::name('stats_user_day')->field('user_id,SUM(total_recharge) total_recharge, SUM(total_cashout) total_cashout, SUM(total_valid) total_valid,SUM(total_winlose) total_winlose')->group('user_id')->where($where_users)->select();
        $data = [];
        foreach ($res as $k => $v) {
            $data[$k] = $v;
            $stat_row = arr_row($stats, 'user_id', $v['id']);
           
            $data[$k]['total_recharge'] = (string)(float)@$stat_row['total_recharge'];
            $data[$k]['total_cashout']  = (string)(float)@$stat_row['total_cashout'];
            $data[$k]['total_valid']    = (string)(float)@$stat_row['total_valid'];
            $data[$k]['total_winlose']  = -@$stat_row['total_winlose']==0 ? 0 : (string)(float)-@$stat_row['total_winlose'];
        }
        return $this->success(__('success'), ['list'=>$data]);
    }

    /**
     * 下级代理
     * @param string $page   当前页数 
     * @param string $username 姓名|可选
     * @param string $starttime 开始时间|可选|格式2020-01-01
     * @param string $endtime   结束时间|可选|格式2020-01-01
     */
    public function subagent_list(){
        $page   = $this->input('page');
        $username  = $this->input('username');
        $starttime = $this->input('starttime');
        $endtime   = $this->input('endtime');

        //代理列表
        $agent_ids = Db::name('agent')->where("parent_id='{$this->auth->id}' AND status=1")->column('user_id');
        $where = db_where_in('id',$agent_ids);
        if(!empty($username)) $where .= " AND username LIKE '%{$username}%' ";
        $starttime = !empty($starttime) ? strtotime($starttime." 00:00:00") : '';
        $endtime   = !empty($endtime)   ? strtotime($endtime." 23:59:59") : time();
        $where .= " AND jointime BETWEEN '{$starttime}' AND '{$endtime}'";
        $res = Db::name('user')->field('id,username,mobile,logintime,jointime,invite_code')->where($where)->order('id DESC')->page("{$page},20")->select();
        //代理本月统计
        $where_users = db_where_in('user_id', array_column($res, 'id') );
        $stats = Db::name('stats_agent_day')->field('user_id,SUM(total_under) total_under, SUM(total_invite) total_invite, SUM(total_active) total_active, SUM(total_netwin) total_netwin')->group('user_id')->where($where_users)->select();
        $data = [];
        foreach ($res as $k => $v) {
            $data[$k] = $v;
            $stat_row = arr_row($stats, 'user_id', $v['id']);
            $data[$k]['total_under']  = (int)@$stat_row['total_under'];
            $data[$k]['total_invite'] = (int)@$stat_row['total_invite'];
            $data[$k]['total_active'] = (int)@$stat_row['total_active'];
            $data[$k]['total_netwin']  = (string)(float)@$stat_row['total_netwin'];
        }
        return $this->success(__('success'), ['list'=>$data]);
    }

    /**
     * 游戏记录查询
     * @param string $page  当前页数
     * @param string $username 姓名|可选
     * @param string $starttime 开始时间|可选|格式2020-01-01
     * @param string $endtime   结束时间|可选|格式2020-01-01
     * @param string $platform  游戏平台|可选|Datang=大唐游戏,查看全部记录传空字符串
     * @param string $status  状态值|可选|:0=未结算,1=已结算,2=已拒绝,3=取消/退回
     */
    public function game_log(){
        $page = $this->input("page");
        $username = $this->input("username");
        $platform = $this->input("platform");
        $status = $this->input("status");
        $starttime = $this->input("starttime");
        $endtime = $this->input("endtime");
        if(!$page) return $this->error(__('请求参数不完整'));

        //查询用户表
        $where_users = " invite_user_id='{$this->auth->id}' AND is_agent=0 ";
        if($username) $where_users .= " AND username LIKE '%{$username}%' ";
        $user_ids = Db::name('user')->where($where_users)->column('id');
        //查询游戏记录表
        $where = db_where_in('user_id',$user_ids);
        if($platform) $where .= " AND plat_key='{$platform}' ";
        if($status)    $where .= " AND status='{$status}' ";
        if($starttime) $where .= " AND createtime>=".strtotime($starttime." 00:00:00 ");
        if($endtime)   $where .= " AND createtime<=".strtotime($endtime." 23:59:59 ");
        //统计
        $total = GameLogModel::field('SUM(money_bet) money_bet, SUM(money_valid) money_valid, SUM(money_winlose) money_winlose, SUM(money_plat_fee) money_plat_fee, SUM(money_rebate) money_rebate')->where($where)->find();
        $total = [
            'money_bet'      => (string)(float)$total['money_bet'],
            'money_valid'    => (string)(float)$total['money_valid'],
            'money_winlose'  => (string)(float)$total['money_winlose'],
            'money_plat_fee' => $total['money_plat_fee']<0 ? 0 : (string)(float)$total['money_plat_fee'],
            'money_rebate'   => (string)(float)$total['money_rebate'],
        ];
        //列表
        $res = GameLogModel::where($where)->page("{$page},10")->order("createtime DESC")->select();
        $data = [];
        foreach ($res as $k => $v) {
            $data[$k] = $v;
            $data[$k]['money_winlose'] = (string)-$v['money_winlose'];
            $data[$k]['plat_name'] = arr_field(platform_list(), 'key', $v['plat_key'], 'name');
        }
        
        return $this->success(__('success'), [ 'list'=>$data, 'total'=>$total ]);
    }


    //格式化返回数据
    private function _data_format($arr){
        foreach ($arr as $k => $v) {
            $res[$k] = (string)floatval($v);
            if(in_array($k, ['total_under','total_invite','total_invite','total_active'])) $res[$k] = (int)$v;
        }
        return $res;
    }

}
